package agent.monitors;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import org.snmp4j.smi.OctetString;

/**
 * Implementação do TorrentMonitor lendo os dados a partir de um arquivo
 * 
 */
public class ValueReader implements TorrentMonitor{
	//Constantes para indicar os campos no arquivo
	private static final String MAX_UL 		= "maxUl"; 
	private static final String MAX_DL 		= "maxDl"; 
	private static final String MAX_ACTIVE 	= "maxActive"; 
	private static final String PEX 		= "pex"; 
	private static final String PORT 		= "port"; 
	private static final String FILE_TOKEN 	= "file";

	private File fileValues;
	
	public ValueReader(String filePath){
		fileValues = new File(filePath);
		this.validate();
	}
	public ValueReader(File file){
		fileValues = file;
		this.validate();
	}
	
	/**
	 * Método que busca no arquivo o valor para um determinado parametro
	 * @param paramName
	 * @return
	 *
	 * @author Daniel Krahn
	 */
	protected String find(String paramName) {
	    BufferedReader in = null;
	    String value = null;
	    try {
		    in = new BufferedReader(new FileReader(fileValues));
		    String line = in.readLine();
		    
		    while (line != null) {
		        if (line.startsWith(paramName)) {
		            value = line.substring(line.indexOf('=')+1).trim();
		            break;
		        }
		        line = in.readLine();
		    }
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(in != null){
				try { 
					in.close(); 
				} catch (IOException e) {
					/* Nada para fazer */
				}
			}
		}
	    return value;
    }
	
	protected boolean validate(){
		return true;
	}
	
	@Override
	public String getMaxUl() {
		return find(MAX_UL);
	}

	@Override
	public String getMaxDl() {
		return find(MAX_DL);
	}

	@Override
	public String getMaxActive() {
		return find(MAX_ACTIVE);
	}

	@Override
	public String getPex() {
		return find(PEX);
	}

	@Override
	public String getPort() {
		return find(PORT);
	}
	
	@Override
	public List<TorrentFile> getFileEntry() {
	    BufferedReader in = null;
	    List<TorrentFile> results = new ArrayList<TorrentFile>();
	    try {
		    in = new BufferedReader(new FileReader(fileValues));
		    String line = in.readLine();
		    String[] lineValue;
		    while (line != null) {
		        if (line.startsWith(FILE_TOKEN)) {
		        	lineValue = line.substring(line.indexOf('=')+1).trim().split("\t");
		        	if(lineValue.length == 12){ //Número de colunas
		        		results.add(new TorrentFile(lineValue));
		        	}
		        }
		        line = in.readLine();
		    }
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(in != null){
				try { 
					in.close(); 
				} catch (IOException e) {
					/* Nada para fazer */
				}
			}
		}
	    return results;
    }

	protected void saveValue(String paramName, String value) {
	    List<String> lines = new ArrayList<String>();
	    boolean changedSomething = false;
	    //Busca definições do arquivo
	    BufferedReader in = null;
	    try {
		    in = new BufferedReader(new FileReader(fileValues));
		    String line = in.readLine();
		    while (line != null) {
		        if ((line.startsWith(paramName)) && (line.substring(line.indexOf('=')+1).trim() != value.trim())) {
		            line = paramName + " = " + value;
		            changedSomething = true;
		        }
		        lines.add(line);
		        line = in.readLine();
		    }
	    
			in.close();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	    
	    //Só salva no arquivo se mudou algo
	    if (changedSomething){
		    PrintWriter out = null;
			try {
				out = new PrintWriter(fileValues);
				for (String l : lines){
			        out.println(l);
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} finally {
				out.close();
			}
	    }
    }
	
	@Override
	public void setMaxUl(OctetString newValue) {
		this.saveValue(MAX_UL, newValue.toString());
	}

	@Override
	public void setMaxDl(OctetString newValue) {
		this.saveValue(MAX_DL, newValue.toString());
	}

	@Override
	public void setMaxActive(OctetString newValue) {
		this.saveValue(MAX_ACTIVE, newValue.toString());
	}

	@Override
	public void setPex(OctetString newValue) {
		this.saveValue(PEX, newValue.toString());
	}

	@Override
	public void setPort(OctetString newValue) {
		this.saveValue(PORT, newValue.toString());
	}
}
